<template>
  <div class="page" v-loading="loading" element-loading-text="加载中...">
    <div class="group_3">
      <div class="section-header">
        <div class="section-title">
          <div class="title-bar"></div>
          <h2>更改任务</h2>
        </div>
      </div>
      <!-- 任务基本信息卡片 -->
      <div class="info-card">
        <div class="info-header">
          <div class="left-section">
            <h1 class="job-title">{{ job.title || "任务标题" }}</h1>
            <div class="tag-container">
              <el-tag
                  v-for="(tag, index) in processedTags"
                  :key="index"
                  size="medium"
                  effect="plain"
                  class="mr-2"
              >
                {{ tag }}
              </el-tag>
            </div>
            <div class="basic-info">
              <div class="info-item">
                <i class="el-icon-money"></i>
                <span class="reward">{{ job.money || 0 }}r/题</span>
              </div>

              <div class="info-item">
                <i class="el-icon-user"></i>
                <span
                >已报名: {{ job.joinedPeople || 0 }}/{{
                    job.totalParticipants || 1
                  }}</span
                >
              </div>
              <div class="info-item">
                <i class="el-icon-time"></i>
                <span>截止日期：{{ formattedEndTime }}</span>
              </div>
              <div class="info-item">
                <i class="el-icon-s-operation"></i>
                <span
                >{{ job.groupCount || 1 }}组 ×
                  {{ job.groupSize || 1 }}人</span
                >
              </div>
              <div class="info-item" v-if="job.enableAI">
                <i class="el-icon-cpu"></i>

                <span class="ai-info">
                  {{ job.aiMode === "internal" ? "内置AI" : "外置AI" }}
                  <el-tag
                      size="mini"
                      :type="job.useMirror ? 'warning' : 'info'"
                      class="ai-tag"
                  >
                    {{ job.useMirror ? "镜像" : "普通" }}
                  </el-tag>
                </span>
              </div>
            </div>
          </div>
          <div class="right-section">
            <img :src="backgroundImage" class="job-image" alt="任务图片"/>
          </div>
        </div>

        <!-- 添加任务描述区域 -->
        <div class="description-section">
          <div class="section-header">
            <div class="section-title">
              <div class="title-bar"></div>
              <h2>基本要求</h2>
            </div>
          </div>
          <div class="description-content">
            <!-- Quill编辑器 -->
            <div ref="quillEditor" class="quill-editor"></div>
          </div>
        </div>

        <el-alert
            v-if="job.notice"
            :title="job.notice"
            type="warning"
            :closable="false"
            show-icon
            class="mt-4"
        />
      </div>
    </div>
  </div>
</template>

<script>
import Quill from "quill";
import "quill/dist/quill.snow.css";
import {Client} from "@stomp/stompjs";
import config from "@/config";
import {fetchGroupChatMessages, fetchJobDataWithStatus} from "@/api/api";
import {getToken} from "@/api/auth";
import {mapGetters} from "vuex";

export default {
  components: {},
  data() {
    return {
      jobId: null,
      groupId: null,
      groupName: "",
      // WebSocket客户端
      stompClient: null,
      // AI助手选项配置
      assistant_options: [
        {
          value: "0",
          label: "不协作",
        },
        {
          value: "1",
          label: "外置协作",
        },
        {
          value: "2",
          label: "内置协作",
        },
      ],
      leftDivWidth: 50,
      rightDivWidth: 50,
      containerHeight: 369,
      editorHeight: 329,
      assistant_value: "0",
      job: {
        description: "",
      }, // 活动详情数据
      conversations: [],
      messages: [],
      newMessage: "",
      concurrentConversationId: null,
      isJoined: false,
      loading: false,
      backgroundImage: "",
      imageLoadError: false,
      userAvatar: require("@/assets/images/default-avatar.jpg"), // 添加默认用户头像
      aiAvatar: require("@/assets/images/ai-avatar.jpg"), // 添加默认AI头像
      quill: null, // 添加 quill 实例引用
      isQuillInitialized: false, // 添加标记，记录编辑器是否已初始化
      isAtQwenMode: false, // 添加@qwen模式标记
    };
  },

  watch: {
    $route: {
      immediate: true,
      handler(to) {
        const newJobId = to.params.id || to.query.id;
        if (newJobId && newJobId !== this.jobId) {
          // 如果路由中的jobId变化了，更新本地jobId并重新获取数据
          this.jobId = newJobId;
          localStorage.setItem("current_job_id", this.jobId);
          this.fetchJobData();
        }
      },
    },
    "job.imageSrc": {
      handler() {
        this.loadBackgroundImage();
      },
      immediate: true,
    },
  },

  methods: {
    // 保存UI设置到localStorage
    saveUISettings() {
      if (this.jobId) {
        const settings = {
          leftDivWidth: this.leftDivWidth,
          rightDivWidth: this.rightDivWidth,
          assistant_value: this.assistant_value,
        };
        const key = `job_ui_${this.jobId}`;
        localStorage.setItem(key, JSON.stringify(settings));
        console.log("UI设置已保存到localStorage，键名:", key);
      }
    },

    // 从localStorage恢复UI设置
    restoreUISettings() {
      if (this.jobId) {
        try {
          const key = `job_ui_${this.jobId}`;
          const savedSettings = localStorage.getItem(key);
          if (savedSettings) {
            const settings = JSON.parse(savedSettings);
            this.leftDivWidth = settings.leftDivWidth || 50;
            this.rightDivWidth = settings.rightDivWidth || 50;
            this.assistant_value = settings.assistant_value || "0";
            console.log("已从localStorage恢复UI设置，键名:", key);
          }
        } catch (error) {
          console.error("恢复UI设置失败:", error);
        }
      }
    },

    // 更新容器和编辑器高度
    updateHeights() {
      const parentHeight = this.$refs.parentContainer?.offsetHeight;
      if (parentHeight) {
        console.log("更新容器高度:", parentHeight);
        this.containerHeight = parentHeight;
        this.editorHeight = parentHeight - 80; // 减去上下padding
      }
    },

    // 根据内容动态调整编辑器高度
    adjustHeight(initialHeight) {
      if (!this.quill || !this.$refs.quillEditor) return;

      const editorContent = this.$refs.quillEditor.querySelector(".ql-editor");
      if (editorContent) {
        console.log("调整编辑器高度:", editorContent.offsetHeight);
        const delta = this.quill.getContents();
        let contentHeight = Math.max(initialHeight, 200); // 设置最小高度为200px

        // 计算文本和图片内容的总高度
        delta.ops.forEach((op) => {
          if (typeof op.insert === "string") {
            // 优化文本行高计算
            const lines = op.insert.split("\n").length;
            const lineHeight = 24; // 设置更合理的行高
            contentHeight += lines * lineHeight;
          } else if (op.insert.image) {
            // 为图片添加合适的间距
            contentHeight += 350 + 20; // 图片高度 + 上下间距
          }
        });

        // 限制最大高度
        const maxHeight = 800;
        contentHeight = Math.min(contentHeight, maxHeight);

        // 更新编辑器和容器高度
        this.$refs.quillEditor.style.height = `${contentHeight}px`;
        this.editorHeight = contentHeight;
        this.containerHeight = contentHeight + 80;

        // 触发重新计算布局
        this.$nextTick(() => {
          window.dispatchEvent(new Event('resize'));
        });
      }
    },

    // 保存消息到localStorage
    saveMessages() {
      if (this.messages && this.messages.length > 0 && this.jobId) {
        const key = `job_messages_${this.jobId}`;
        localStorage.setItem(key, JSON.stringify(this.messages));
        console.log("聊天消息已保存到localStorage，键名:", key);
      }
    },

    // 从localStorage恢复消息
    restoreMessages() {
      if (this.jobId) {
        try {
          const key = `job_messages_${this.jobId}`;
          const savedMessages = localStorage.getItem(key);
          if (savedMessages) {
            this.messages = JSON.parse(savedMessages);
            console.log("已从localStorage恢复聊天消息，键名:", key);

            // 确保在消息恢复后滚动到底部
            this.$nextTick(() => {
              this.scrollToBottom();
            });
          }
        } catch (error) {
          console.error("恢复聊天消息失败:", error);
        }
      }
    },

    // WebSocket相关方法
    initWebSocket() {
      if (this.stompClient) {
        this.disconnectWebSocket();
      }

      const token = getToken();
      if (!token || !this.groupId) {
        console.log("无法初始化WebSocket：缺少token或groupId");
        return;
      }

      // 从代理配置中获取实际的后端地址
      const backendUrl = config.dev.proxyTable["/api"].target;
      const wsUrl = backendUrl.replace("http://", "ws://");
      const fullWsUrl = `${wsUrl}ws`;
      console.log("WebSocket URL:", fullWsUrl);

      this.stompClient = new Client({
        brokerURL: fullWsUrl,
        connectHeaders: {
          Authorization: `Bearer ${token}`,
        },
        debug: (str) => {
          console.log("STOMP Debug:", str);
        },
        onConnect: (frame) => {
          console.log("WebSocket连接成功");

          try {
            // 订阅群组消息
            this.stompClient.subscribe(
                `/topic/group/${this.groupId}`,
                this.onMessageReceived,
                {Authorization: `Bearer ${token}`}
            );

            // 订阅私人消息
            this.stompClient.subscribe(
                "/queue/messages",
                this.onMessageReceived,
                {Authorization: `Bearer ${token}`}
            );
          } catch (error) {
            console.error("订阅消息失败:", error);
          }
        },
        onStompError: (frame) => {
          console.error("STOMP错误:", frame);
        },
      });

      try {
        this.stompClient.activate();
      } catch (error) {
        console.error("WebSocket连接激活失败:", error);
      }
    },

    onMessageReceived(message) {
      try {
        const receivedMessage = JSON.parse(message.body);
        console.log("收到新消息:", receivedMessage);

        // 将新消息添加到消息列表
        this.messages.push(receivedMessage);

        // 保存消息到localStorage
        this.saveMessages();

        // 滚动到底部
        this.$nextTick(() => {
          this.scrollToBottom();
        });
      } catch (error) {
        console.error("处理消息失败:", error);
      }
    },

    disconnectWebSocket() {
      if (this.stompClient) {
        try {
          this.stompClient.deactivate();
          console.log("WebSocket连接已断开");
        } catch (error) {
          console.error("断开WebSocket连接时出错:", error);
        }
      }
    },

    initializeQuill() {
      const editor = this.$refs.quillEditor;
      if (!editor || this.isQuillInitialized) return;

      this.quill = new Quill(editor, {
        theme: "snow",
        modules: {
          toolbar: [
            ["bold", "italic", "underline", "strike"],
            ["blockquote", "code-block"],
            [{header: 1}, {header: 2}],
            [{list: "ordered"}, {list: "bullet"}],
            [{script: "sub"}, {script: "super"}],
            [{indent: "-1"}, {indent: "+1"}],
            [{direction: "rtl"}],
            [{size: ["small", false, "large", "huge"]}],
            [{header: [1, 2, 3, 4, 5, 6, false]}],
            [{color: []}, {background: []}],
            [{font: []}],
            [{align: []}],
            ["clean"],
          ],
        },
        placeholder: "请输入任务描述",
      });

      // 设置初始内容
      if (this.job) {
        this.quill.root.innerHTML = this.job.description;
      }

      // 监听内容变化
      this.quill.on("text-change", () => {
        this.job.description = this.quill.root.innerHTML;
      });

      this.isQuillInitialized = true;

      console.log("Quill编辑器已初始化");
      // 从localStorage恢复编辑器内容
      this.restoreEditorContent();

      // 监听内容变化，动态调整高度并保存内容
      this.quill.on("text-change", () => {
        this.$nextTick(() => {
          this.adjustHeight(329);
          this.saveEditorContent();
        });
      });
    },

    // 保存编辑器内容到localStorage
    saveEditorContent() {
      if (this.quill && this.jobId) {
        const content = this.quill.getContents();
        const key = `job_editor_${this.jobId}`;
        localStorage.setItem(key, JSON.stringify(content));
        console.log("编辑器内容已保存到localStorage，键名:", key);
      }
    },

    // 从localStorage恢复编辑器内容
    restoreEditorContent() {
      if (this.quill && this.jobId) {
        try {
          const key = `job_editor_${this.jobId}`;
          const savedContent = localStorage.getItem(key);
          if (savedContent) {
            const content = JSON.parse(savedContent);
            this.quill.setContents(content);
            console.log("已从localStorage恢复编辑器内容，键名:", key);
          }
        } catch (error) {
          console.error("恢复编辑器内容失败:", error);
        }
      }
    },

    async fetchJobData() {
      try {
        console.log("开始加载任务数据，jobId:", this.jobId);
        this.loading = true;
        const {jobData, joinStatus} = await fetchJobDataWithStatus(
            this.jobId
        );

        console.log("获取到任务数据:", jobData);
        console.log("获取到报名状态:", joinStatus);

        this.job = jobData;
        this.isJoined = joinStatus;
        this.loadBackgroundImage();

        // 在获取到数据后初始化Quill编辑器
        this.$nextTick(() => {
          this.initializeQuill();
        });

        this.loading = false;
        console.log("任务数据加载完成");
      } catch (error) {
        console.error("获取数据失败:", error);
        this.$message.error("获取数据失败，请稍后重试");
        this.loading = false;

        // 如果API请求失败，尝试从localStorage恢复基本数据
      }
    },

    getImageUrl() {
      // 如果有图片链接就使用
      if (this.job.imageSrc && this.job.imageSrc.trim()) {
        return encodeURI(this.job.imageSrc.trim());
      }
      // 否则使用本地默认图片
      return require("@/assets/images/default-king.png");
    },

    loadBackgroundImage() {
      const url = this.getImageUrl().replace("https://", "http://");
      const img = new Image();

      img.onload = () => {
        this.backgroundImage = url;
        this.imageLoadError = false;
      };

      img.onerror = () => {
        console.error("Image load failed:", url);
        this.backgroundImage = require("@/assets/images/default-king.png");
        this.imageLoadError = true;
      };

      img.src = url;
    },
    // 添加滚动到底部的方法
    scrollToBottom() {
      const container = this.$refs.messageContainer;
      if (container) {
        container.scrollTop = container.scrollHeight;
      }
    },
  },
  computed: {
    ...mapGetters(["toDetail"]),
    processedTags() {
      if (!this.job.tags) return ["暂无"];
      return typeof this.job.tags === "string"
          ? this.job.tags.split(",").map((tag) => tag.trim())
          : this.job.tags;
    },
    formattedEndTime() {
      if (!this.job.endTime) return "未知时间";
      const date = new Date(this.job.endTime);
      const year = date.getFullYear();
      const month = (date.getMonth() + 1).toString().padStart(2, "0");
      const day = date.getDate().toString().padStart(2, "0");
      const hour = date.getHours().toString().padStart(2, "0");
      const minute = date.getMinutes().toString().padStart(2, "0");
      return `${year}年${month}月${day}日 ${hour}:${minute}`;
    },
    getJoinButtonText() {
      if (this.isJoined) {
        return "已报名";
      }
      if (this.job.joinedPeople >= this.job.totalParticipants) {
        return "名额已满";
      }
      return "立即报名";
    },
    sortedMessages() {
      return [...this.messages].sort((a, b) => {
        const timeA = new Date(a.created_at).getTime();
        const timeB = new Date(b.created_at).getTime();
        return timeA - timeB;
      });
    },
  },
  // 生命周期钩子
  created() {
    // 从路由参数或URL中获取jobId
    this.jobId = this.$route.params.id || this.$route.query.id;

    // 如果没有从路由获取到，尝试从localStorage恢复
    if (!this.jobId) {
      this.jobId = localStorage.getItem("current_job_id");
    }

    if (this.jobId) {
      // 保存当前jobId到localStorage
      localStorage.setItem("current_job_id", this.jobId);

      // 先恢复UI设置
      this.restoreUISettings();
      // 然后获取任务数据
      this.fetchJobData();
    } else {
      this.$message.error("无法获取任务ID，请返回任务列表重新选择");
    }
  },

  mounted() {
    // 确保在mounted中也能获取到正确的jobId
    if (!this.jobId) {
      this.jobId =
          this.$route.params.id ||
          this.$route.query.id ||
          localStorage.getItem("current_job_id");
      if (this.jobId) {
        localStorage.setItem("current_job_id", this.jobId);
        this.fetchJobData();
      }
    }
  },

  beforeDestroy() {
    // 保存所有数据
    if (this.quill) {
      this.saveEditorContent();
    }
    this.saveMessages();
    this.saveUISettings();

    // 保存报名状态
    if (this.jobId && this.isJoined) {
      localStorage.setItem(
          `job_joined_${this.jobId}`,
          JSON.stringify(this.isJoined)
      );
    }

    // 保存群组信息
    if (this.jobId && this.groupId) {
      localStorage.setItem(`job_group_${this.jobId}`, this.groupId);
      if (this.groupName) {
        localStorage.setItem(`job_group_name_${this.jobId}`, this.groupName);
      }
    }

    // 清理事件监听
    window.removeEventListener("resize", this.updateHeights);
    // 组件销毁前清理编辑器
    if (this.quill) {
      this.quill.off();
      this.quill = null;
      this.isQuillInitialized = false;
    }
    // 断开WebSocket连接
    this.disconnectWebSocket();
  },

  // 添加activated和deactivated生命周期钩子（用于keep-alive组件）
  activated() {
    if (this.groupId) {
      this.initWebSocket();
    }
  },

  deactivated() {
    this.disconnectWebSocket();
  },
};
</script>

<style scoped lang="css">
/* Quill编辑器样式 */
.quill-editor {
  height: 300px;
  margin-bottom: 20px;
}

:deep(.ql-toolbar.ql-snow) {
  border: 1px solid #dcdfe6;
  border-bottom: none;
  border-radius: 4px 4px 0 0;
  background-color: #f5f7fa;
}

:deep(.ql-container.ql-snow) {
  border: 1px solid #dcdfe6;
  border-radius: 0 0 4px 4px;
}

:deep(.quill-editor) {
  min-height: 200px;
  font-size: 14px;
  line-height: 1.6;
  color: #606266;
}

:deep(.quill-editor h1),
:deep(.quill-editor h2),
:deep(.quill-editor h3) {
  font-weight: 600;
  line-height: 1.4;
  margin: 0.5em 0;
}

:deep(.quill-editor h1) {
  font-size: 1.5em;
}

:deep(.quill-editor h2) {
  font-size: 1.3em;
}

:deep(.quill-editor h3) {
  font-size: 1.1em;
}

:deep(.quill-editor p) {
  margin: 0.5em 0;
}

:deep(.quill-editor ul),
:deep(.quill-editor ol) {
  padding-left: 1.5em;
  margin: 0.5em 0;
}

:deep(.quill-editor li) {
  margin-bottom: 0.3em;
}

:deep(.quill-editor img) {
  max-width: 100%;
  margin: 0.5em 0;
  border-radius: 4px;
}

:deep(.quill-editor blockquote) {
  border-left: 3px solid #e6e8eb;
  margin: 0.5em 0;
  padding-left: 1em;
  color: #909399;
}

.page {
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
  padding: 20px;
}

.group_3 {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 20px;
  width: 100%;
}

.info-card {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.file-sharing-container .section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.section-header {
  margin-bottom: 20px;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 10px;
}

.title-bar {
  width: 4px;
  height: 20px;
  background: #409eff;
  border-radius: 2px;
}

h2 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.file-sharing-container .section-title {
  display: flex;
  align-items: center;
  gap: 10px;
}

.file-sharing-container .title-bar {
  width: 4px;
  height: 20px;
  background: #409eff;
  border-radius: 2px;
}

.file-sharing-container h2 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.file-name-cell i {
  color: #909399;
  font-size: 16px;
}

.info-header {
  display: flex;
  justify-content: space-between;
  gap: 40px;
}

.left-section {
  flex: 1;
}

.job-title {
  font-size: 28px;
  font-weight: bold;
  color: #303133;
  margin: 0 0 16px 0;
}

.tag-container {
  margin-bottom: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.basic-info {
  display: flex;
  gap: 24px;
  color: #606266;
  flex-wrap: wrap;
  align-items: center;
}

.info-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}

.info-item i {
  font-size: 16px;
}

.el-icon-cpu {
  color: #409eff;
}

.el-icon-s-operation {
  color: #67c23a;
}

.ai-info {
  display: flex;
  align-items: center;
  gap: 6px;
}

.ai-tag {
  transform: scale(0.8);
  transform-origin: left center;
}

.reward {
  color: #e6a23c;
  font-weight: bold;
  font-size: 18px;
  font-family: Cera-Bold, sans-serif;
}

.right-section {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 16px;
}

.job-image {
  width: 240px;
  height: 160px;
  object-fit: cover;
  border-radius: 8px;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 添加描述区域样式 */
.description-section {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid #ebeef5;
}

.section-header {
  margin-bottom: 20px;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.title-bar {
  width: 4px;
  height: 20px;
  background-color: #e66721;
  border-radius: 2px;
}

.section-title h2 {
  font-size: 20px;
  font-weight: bold;
  color: #303133;
  margin: 0;
}

.description-content {
  padding: 20px;
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

/* Quill 编辑器内容样式 */
.quill-editor {
  padding: 0;
  min-height: auto;
}

/* 确保 Quill 内容样式正确显示 */
:deep(.quill-editor) {
  font-size: 14px;
  line-height: 1.6;
  color: #606266;
}

:deep(.quill-editor p) {
  margin-bottom: 1em;
}

:deep(.quill-editor h1),
:deep(.quill-editor h2),
:deep(.quill-editor h3) {
  font-weight: 600;
  line-height: 1.4;
  margin: 1em 0 0.5em;
}

:deep(.quill-editor h1) {
  font-size: 1.5em;
}

:deep(.quill-editor h2) {
  font-size: 1.3em;
}

:deep(.quill-editor h3) {
  font-size: 1.1em;
}

:deep(.quill-editor ul),
:deep(.quill-editor ol) {
  padding-left: 1.5em;
  margin-bottom: 1em;
}

:deep(.quill-editor li) {
  margin-bottom: 0.5em;
}

:deep(.quill-editor img) {
  max-width: 100%;
  margin: 1em 0;
  border-radius: 4px;
}

:deep(.quill-editor blockquote) {
  border-left: 4px solid #e6e8eb;
  margin: 1em 0;
  padding-left: 1em;
  color: #909399;
}

:deep(.quill-editor code) {
  background-color: #f5f7fa;
  padding: 0.2em 0.4em;
  border-radius: 3px;
  font-family: Cera-Bold, sans-serif;
}

:deep(.quill-editor pre) {
  background-color: #f5f7fa;
  padding: 1em;
  border-radius: 4px;
  overflow-x: auto;
}

/* 链接样式 */
:deep(.quill-editor a) {
  color: #409eff;
  text-decoration: none;
  transition: color 0.3s ease;
}

:deep(.quill-editor a:hover) {
  color: #66b1ff;
  text-decoration: underline;
}

/* 表格样式 */
:deep(.quill-editor table) {
  border-collapse: collapse;
  width: 100%;
  margin: 1em 0;
}

:deep(.quill-editor td),
:deep(.quill-editor th) {
  padding: 0.5em;
}

:deep(.quill-editor th) {
  background-color: #f5f7fa;
  font-weight: bold;
}

/* 列表样式 */
:deep(.quill-editor ul > li::before) {
  content: "•";
  margin-right: 0.5em;
  color: #909399;
}

:deep(.quill-editor ol) {
  counter-reset: list-counter;
}

:deep(.quill-editor ol > li::before) {
  counter-increment: list-counter;
  content: counter(list-counter) ".";
  margin-right: 0.5em;
  color: #909399;
}

/* 调整工作区域的上边距 */

.join-button {
  min-width: 120px;
  width: 200px;
  height: 40px;
  font-size: 16px;
  font-weight: 500;
}

.join-button:disabled {
  cursor: not-allowed;
}

.join-button-container {
  display: flex;
  justify-content: center;
  margin-top: 24px;
}

.ql-container.ql-snow {
  border: 0px solid #ccc;
}

/* 未报名时的占位样式 */
</style>
